import LXCOM from '../common/common.js'
import { LGXEnums } from '../common/sysenum.js'

import UtilFuncs from '../common/tools/utilfuncs.js'
var funcs = UtilFuncs.UtilFuncs;

import GlobalConst from '../common/globalConst.js'
var global = GlobalConst.GlobalConst;

import { GraphModifySvc } from './graphmodsvc.js'
import { LGXMatrix } from '../common/struct/math/matrix.js';
import Coord from '../common/struct/coord.js'
import { KeyGenerator } from '../common/keygenerator.js';

import { CoordTRFUtil } from '../common/tools/coordtool.js';
import { PositionUtil } from '../common/tools/positionutil.js';


class LineUnitCounter {
    static instance = null;
    constructor() {
        if (LineUnitCounter.instance) {
            return LineUnitCounter.instance;
        }
        LineUnitCounter.instance = this;
        this.lineUnitCount = 0;
    }
}

class TransformInfo {
    constructor() {
        this.sx = 1;
        this.sy = 1;
        this.orinPt = { x: 0, y: 0 };
        this.rotRad = 0;
        this.isClipFlag = false;
    }

    cloneCopy(src) {
        let ret = new TransformInfo();
        ret.sx = src.sx;
        ret.sy = src.sy;
        ret.orinPt.x = src.orinPt.x;
        ret.orinPt.y = src.orinPt.y;
        ret.rotRad = src.rotRad;
        ret.isClipFlag = src.isClipFlag;
        return ret;
    }
    rotate_degree(degree) {
        this.rotRad += funcs.degree2Radian(degree);
    }

    scale(sx, sy) {
        this.sx *= sx;
        this.sy *= sy;
    }

    translate(tx, ty) {
        this.orinPt.x += tx;
        this.orinPt.y += ty;
    }
}

class AbsGraph {
    static lineUnitCount = 0;
    constructor(type) {
        this.m_gid = 0;//图形ID，整型，单幅图内唯一
        this.m_rid = ""; //对象ID，UUID，全系统唯一，同一个对象在不同图内此ID相同
        this._type = type;//.toString(16);//图形类型ID

        this.m_topoRes = null;
        this.m_layer = null;
        this.m_graphType = LGXEnums.LGXGraphType.AbstractGraph_type;

        this._refSymbol = null;
        this._position = null;
        this._startFlag = 0;
        this._finishFlag = 0;
        this._useful = 1;
        this._newAddFlag = 0;
        this._selected = 0;
        this._selKind = 0;
        this._actionSvc = null;
        this._zone = new LXCOM.LGXRect(0, 0, 0, 0);
        this._modifing = 0;
        this._modified = 0;
        this._highLight = 0;
        this._angle = 0;//角度值，逆时针为正

        this._name = "";
        this.m_pContainer = null;
        this.m_tChildGraphLst = new Array();//作为容器图形，其包含的子图形队列
        this.m_pLabelGraph = null;
        this._lockFlag = false;
        this.mouseDownTime = 0;
        this.dataChgObserverList = [];//数据发生变化需要通知的观察者队列

        this.localScale = { x: 1, y: 1 };
        this.xlink = "";
        this.labelCtrlFlag = 0;//图形关联文本标签控制标识，0--自由移动 1---限制在本图形包围盒中
        this._notifyFlag = true;
    }

    display(map, mapInfo, forClip) { }
    disInSymbol(transformInfo, map, mapInfo) { }
    calScope(mapscale) { }
    distance(tPos, scaling, mapscale) { }

    getMainFeaturePTLst(tFeaturePTLst, transformInfo) { }
    getSubFeaturePTLst(tFeaturePTLst, mousePoint, transformInfo) { }

    assignInfo(info) { }
    toInfo() { }
    getPosCopy() { }
    modifyAttribute(info, mapscale) { }
    calculateSubKind(tPoint, scaling, mapscale) { }

    getLocalZone() { }
    calculateSubControlPoint(tPoint, scaling, mapscale) { return 0; }
    getCoordInfo() { }
    modifyCoord(propName, propVal, mapscale) { }
    calControlPoint() { }
    getMouseDownTime() { return this.mouseDownTime; }
    getDimDatumFeatureLst() { }//每个图形标注时，可作为标注基准的特征列表
    translateGradientFill(tOffset) { }
    getLocalOrigin() { return this._zone.getCnt(); }
    chPtOnEdge(mousePoint, scaling) { return false; }//检测mousePoint点是否落在当前图形对象的边界上
    clipFillZone(map, mapInfo, transformInfo) {
        map.clip();
        if (!transformInfo) {
            this.display(map, mapInfo, true);
        }
        else {
            this.disInSymbol(transformInfo, map, mapInfo, true);
        }
        return 0;
    }//裁剪填充区域

    //标注值发生变化的响应函数---旧
    onChgDimValue(dimGraph, oldValue, newValue) {
        console.log("error,absgraph onChgDimValue******");
    }
    //标注基准图形坐标发生变化的响应函数
    onDimBaseChged(dimGraph) {
        console.log("error,absgraph onDimBaseChged******");
    }

    //标注值发生变化的响应函数
    onDimDatumValueChgd(chgDatum, preDatumPt) {

    }

    //复制粘贴时，从复制源对象复制属性到本图形对应属性
    copyPropFromBuf(bufInfo, tx, ty) {
        this._angle = bufInfo.angle;
        this.xlink = bufInfo.xlink;

        let pos = this.getPos();
        pos.clone(bufInfo.pos);
        pos.offset(tx, ty);
        this.copySubPropFromBuf(bufInfo, tx, ty);
        this.calScope(1);
    }

    //复制粘贴时，从复制源对象复制属性到本图形对应属性----虚函数，由实体继承类实现
    copySubPropFromBuf(bufInfo, tx, ty) {

    }


    setCoordCorrectSvc(svc) {
        if (this._actionSvc) {
            this._actionSvc.setCoordCorrectSvc(svc);
        }
    }


    convertWorldPt2Screen(pt, mapinfo, transformInfo) {
        return CoordTRFUtil.world2Screen(pt, mapinfo);
    }

    convertLocalPt2Screen(pt, mapinfo, transformInfo) {
        let wpt = CoordTRFUtil.transLocalPt2World(pt, 0, transformInfo);
        return CoordTRFUtil.world2Screen(wpt, mapinfo);
    }

    //局部坐标系，随着旋转、平移、缩放而发生变化
    //只用于坐标变换计算中，显示仍使用世界坐标系
    getLocalMatrix() {
        let mtx = new LGXMatrix();
        let cnt = this.getLocalOrigin();
        mtx.SetR({ x: 0, y: 0, z: this.getAngle() });
        mtx.SetT({ x: cnt.x, y: cnt.y, z: 0 });
        return mtx;
    }

    initCommProp(obj) {
        this.m_gid = obj.gid;
        this.m_rid = obj.rid;
        this.type = obj.type;
        this._position.clone(obj.pos);
        this._finishFlag = 1;
        this._startFlag = 1;
        this._angle = obj.angle;
        this.setLink(obj.xlink);
    }
    commoneProp2Info(info) {
        info.kind = 0;
        info.type = this._type;
        info.superID = 0;
        if (this.m_pContainer) {
            info.superID = this.m_pContainer.m_gid;
        }
        info.modifyType = LGXEnums.ModifyType.NoneType_mod;
        info.m_nUseful = this._useful;
        info.m_nNewAdd = this._newAddFlag;

        if (!this.m_rid || this.m_rid == "") {
            this.m_rid = KeyGenerator.rid();
        }
        info.gid = this.m_gid;
        info.rid = this.m_rid;
        info.scope_left = this._zone.left;
        info.scope_top = this._zone.top;
        info.scope_right = this._zone.right;
        info.scope_bottom = this._zone.bottom;
        if (this._refSymbol) {
            info.sSymbolName = this._refSymbol.name;
        }
        info.xlink = this.xlink;
        info.inLayIdx = 0;//在逻辑图层中的顺序，默认为-1，表示放在队尾
        if (this.m_layer) {
            info.layerName = this.m_layer.name;
        }
        info.angle = this._angle;//角度值
        info.pos.clone(this._position);
        info.state = 0;
    }

    act2Mouse(mosEvnt, worldPos) {
        var ret = "none_state";
        if (this._actionSvc != null) {
            ret = this._actionSvc.act2Mouse(mosEvnt, worldPos);
        }
        this.notifyToObserver();
        return ret;
    }

    calculateSelKind(tPoint, scaling, mapscale) {
        if (!this.preCheckInScope(tPoint, scaling)) {
            return 0;
        }
        let selSubGraphControlPointKind = this.calculateSubControlPoint(tPoint, scaling, mapscale);
        if (selSubGraphControlPointKind == 0) {
            var ptlst = this.getScopeVertexPtLst(scaling);
            var seleKind = 0;
            var tAbsorbPt = new LXCOM.LGXPoint();
            tAbsorbPt.clone(tPoint);
            let minDis = -1;
            var cmpGap = global.FocusSelGap;
            let lenth = ptlst.length;
            for (var i = 0; i < lenth; i++) {
                let pCntPos = ptlst[i];
                let dis = funcs.distancePoint(tPoint, pCntPos, scaling);
                if (dis <= cmpGap*2 && dis >= 0) {
                    if (minDis < 0) {
                        minDis = dis;
                        seleKind = LGXEnums.LGXModGraphKind.CommonStSelKind + i + 1;
                        tAbsorbPt.clone(tPoint);
                    }
                    else if (minDis > dis) {
                        minDis = dis;
                        seleKind = LGXEnums.LGXModGraphKind.CommonStSelKind + i + 1;
                        tAbsorbPt.clone(tPoint);
                    }
                }
            }

            if (seleKind == 0) {
                if (this.getSelect() > 0 && this.preCheckInScope(tPoint, scaling)) {
                    seleKind = this.calculateSubKind(tPoint, scaling, mapscale);
                    if (seleKind == 0) {
                        seleKind = LGXEnums.LGXModGraphKind.Drag_center;
                    }
                }
                else {
                    seleKind = this.calculateSubKind(tPoint, scaling, mapscale);
                }
            }
        }
        else {
            seleKind = selSubGraphControlPointKind;
        }
        return seleKind;
    }

    displayGraphScope(map, mapInfo, forseDis) {
        if (mapInfo._disScope || forseDis) {
            map.save();
            let leftTop = this._zone.ltPt();
            let botRight = this._zone.rbPt();

            var p1 = CoordTRFUtil.world2Screen(leftTop, mapInfo);
            var p2 = CoordTRFUtil.world2Screen(botRight, mapInfo);
            var left = Math.min(p1.x, p2.x);
            var right = Math.max(p1.x, p2.x);
            var top = Math.min(p1.y, p2.y);
            var bottom = Math.max(p1.y, p2.y);
            var wid = right - left;
            var hgt = bottom - top;

            map.beginPath();
            map.lineWidth = 2;
            map.strokeStyle = "#ff00ff";
            map.rect(left, top, wid, hgt);
            map.stroke();
            map.closePath();
            map.restore();
        }
    }

    displayFeaturePoint(map, mapInfo) {
        if (this._useful != 1 || this._finishFlag != 1 || mapInfo.editMode == "autocad") {
            return;
        }
        var ptlst = this.getScopeVertexPtLst(mapInfo.getScaling());
        this.displayDashLineRectScope(ptlst, map, mapInfo)
        ptlst.length = 0;
        ptlst = null;
    }

    getScopeVertexPtLst(scaling) {
        let orgWorldPt = this.getLocalOrigin();

        var symScope = this.getLocalZone();
        var rotv = this.getRadAngle();
        var rotcnt = { x: 0, y: 0 };
        let x = symScope.left;
        let y = symScope.top;
        var lefttopPt = { x, y };
        var p1 = funcs.rotate(lefttopPt, rotcnt, rotv);
        p1.x = orgWorldPt.x + p1.x;
        p1.y = orgWorldPt.y + p1.y;

        x = symScope.right;
        y = symScope.top;
        var righttopPt = { x, y };
        var p2 = funcs.rotate(righttopPt, rotcnt, rotv);
        p2.x = orgWorldPt.x + p2.x;
        p2.y = orgWorldPt.y + p2.y;

        x = symScope.right;
        y = symScope.bottom;
        var rightbotPt = { x, y };
        var p3 = funcs.rotate(rightbotPt, rotcnt, rotv);
        p3.x = orgWorldPt.x + p3.x;
        p3.y = orgWorldPt.y + p3.y;

        x = symScope.left;
        y = symScope.bottom;
        var leftbotPt = { x, y };
        var p4 = funcs.rotate(leftbotPt, rotcnt, rotv);
        p4.x = orgWorldPt.x + p4.x;
        p4.y = orgWorldPt.y + p4.y;

        var ptlst = new Array();
        ptlst.push(p1);
        ptlst.push(p2);
        ptlst.push(p3);
        ptlst.push(p4);

        x = (p1.x + p2.x) / 2;
        y = (p1.y + p2.y) / 2;
        let topMid = { x, y };
        ptlst.push(topMid);

        x = (p2.x + p3.x) / 2;
        y = (p2.y + p3.y) / 2;
        let rightMid = { x, y };
        ptlst.push(rightMid);

        x = (p3.x + p4.x) / 2;
        y = (p3.y + p4.y) / 2;
        let botMid = { x, y };
        ptlst.push(botMid);

        x = (p4.x + p1.x) / 2;
        y = (p4.y + p1.y) / 2;
        let leftMid = { x, y };
        ptlst.push(leftMid);

        //图符中心点
        x = symScope.getCnt().x;
        y = symScope.getCnt().y;
        var shakeHandBotPt = { x, y };
        var p5 = funcs.rotate(shakeHandBotPt, rotcnt, rotv);
        p5.x = orgWorldPt.x + p5.x;
        p5.y = orgWorldPt.y + p5.y;

        const handHgt = 15;
        //旋转把手顶点
        x = (symScope.left + symScope.right) * 0.5;
        y = symScope.top + handHgt / scaling;
        var shakeHandTopPt = { x, y };
        var p6 = funcs.rotate(shakeHandTopPt, rotcnt, rotv);
        p6.x = orgWorldPt.x + p6.x;
        p6.y = orgWorldPt.y + p6.y;

        ptlst.push(p5);
        ptlst.push(p6);

        return ptlst;
    }

    getZoneInWolrd() {
        var symScope = this.getZone();
        var rotv = this.getRadAngle();
        var x = symScope.getCnt().x;
        var y = symScope.getCnt().y;
        var rotcnt = { x, y };
        x = symScope.left;
        y = symScope.top;
        var lefttopPt = { x, y };
        var p1 = funcs.rotate(lefttopPt, rotcnt, rotv);

        x = symScope.right;
        y = symScope.top;
        var righttopPt = { x, y };
        var p2 = funcs.rotate(righttopPt, rotcnt, rotv);

        x = symScope.right;
        y = symScope.bottom;
        var rightbotPt = { x, y };
        var p3 = funcs.rotate(rightbotPt, rotcnt, rotv);

        x = symScope.left;
        y = symScope.bottom;
        var leftbotPt = { x, y };
        var p4 = funcs.rotate(leftbotPt, rotcnt, rotv);

        var rect = new LXCOM.LGXRect(p1.x, p1.y, p1.x, p1.y);
        var ptlst = new Array();
        ptlst.push(p2);
        ptlst.push(p3);
        ptlst.push(p4);
        ptlst.forEach(p => {
            rect.left = Math.min(p.x, rect.left);
            rect.right = Math.max(p.x, rect.right);
            rect.top = Math.max(p.y, rect.top);
            rect.bottom = Math.min(p.y, rect.bottom);
        });
        return rect;
    }

    drawFocusPoint(map, x, y, color, size) {
        if (!size) {
            size = global.FocusPointSize;
        }
        map.fillStyle = color;
        map.beginPath();
        map.lineWidth = 1;
        map.strokeStyle = color;
        map.fillRect(x - size / 2, y - size / 2, size, size);
        map.stroke();
        map.closePath();
        map.fill();
    }

    preCheckNearFeaturePt(mousePt, scaling) {
        if (!this._selected) {
            return false;
        }
        const cmpGap = global.SelectGap*2;
        let flag = false;
        var ptlst = this.getScopeVertexPtLst(scaling);
        for (let i = 0; i < ptlst.length; i++) {
            let pt = ptlst[i];
            let dis = funcs.distancePoint(mousePt, pt, scaling);
            if (dis <= cmpGap && dis >= 0) {
                flag = true;
                break;
            }
        }
        ptlst.length = 0;
        ptlst = null;
        return flag;
    }

    preCheckInScope(mousePt, scaling) {
        let rect = new LXCOM.LGXRect();
        rect.clone(this._zone);
        rect.expand(global.SelectGap / scaling);
        let flag = funcs.chkPtInRect(mousePt, rect);
        if (!flag) {
            if (this.preCheckNearFeaturePt(mousePt, scaling)) {
                flag = true;
            }
        }
        return flag;
    }

    modifyByOffset(tOffset, modCmdInfo) {
        // console.log("modifyByOffset-------,x:" + tOffset.x + " y:" + tOffset.y);
        let dis = Math.sqrt(tOffset.x * tOffset.x + tOffset.y * tOffset.y);
        if (dis < global.ZERO_4E) {
            return;
        }
        let succes = false;
        if (this.m_graphType == LGXEnums.LGXGraphType.umlpackage_type) {
            this.movePosOffset(tOffset, modCmdInfo);
        }
        else {
            if (this._selKind > LGXEnums.LGXModGraphKind.CommonStSelKind) {
                let list = this.getAllChild();
                if (this.m_pLabelGraph && list.indexOf(this.m_pLabelGraph) == -1) {
                    list.push(this.m_pLabelGraph);
                }
                succes = GraphModifySvc.modify(this, list, tOffset, modCmdInfo.mapscale, modCmdInfo.scaling);
                console.log("succes=" + succes);
            }
            else {
                let actModifyGraph = this;
                // if (this.m_pContainer) {
                //     actModifyGraph = this.m_pContainer;
                // }
                actModifyGraph.movePosOffset(tOffset, modCmdInfo);
                succes = true;
            }
        }
        this.setModifing(1);
        this.calScope(modCmdInfo.mapscale);
        this.notifyToObserver();
        return succes;
    }

    getAllChild() {
        let list = [];
        this.recurve2FindAllChild(list, this);
        return list;
    }

    recurve2FindAllChild(list, graph) {
        for (let i = 0; i < graph.m_tChildGraphLst.length; i++) {
            let child = graph.m_tChildGraphLst[i];
            this.recurve2FindAllChild(list, child);
        }
        if (list.indexOf(graph) == -1) {
            list.push(graph);
        }
    }


    activeFill(map, pos) {
        var grd = null;
        if (this._fillDef.fillStyle == LGXEnums.LGXFillStyle.EMPTY) {
            grd = this._lineDef.color.toHexString();
        }
        else if (this._fillDef.fillStyle == LGXEnums.LGXFillStyle.Radial_CenterToTopMid) {
            grd = map.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, pos.radius);
            grd.addColorStop(0, this._fillDef.stColor.toHexString());
            grd.addColorStop(1, this._fillDef.endColor.toHexString());
        }
        else {
            var left = pos.x - pos.radius;
            var right = pos.x + pos.radius;
            var top = pos.y - pos.radius;
            var bottom = pos.y + pos.radius;
            grd = map.createLinearGradient(left, top, left, bottom);
            grd.addColorStop(0, this._fillDef.stColor.toHexString());
            grd.addColorStop(1, this._fillDef.endColor.toHexString());
        }

        if (this._fillDef.fillStyle == LGXEnums.LGXFillStyle.EMPTY) {
            map.strokeStyle = grd;
            map.stroke();
        }
        else {
            map.fillStyle = grd;
            map.fill();
        }
    }

    dragConnLineEnd(transPt) {
        if (!this.m_topoRes) {
            return;
        }
        var count = this.m_topoRes.m_connNodeList.length;
        for (var i = count - 1; i >= 0; i--) {
            var node = this.m_topoRes.m_connNodeList[i];
            if (node) {
                this.dragNodeConnLines(node, transPt);
            }
        }
    }

    dragNodeConnLines(node, transPt) {
        var count = node.m_connLineList.length;
        for (var i = count - 1; i >= 0; i--) {
            var line = node.m_connLineList[i];
            if (line) {
                this.dragNodeConnLine(node, line, transPt);
            }
        }
        node.translate(transPt);
    }

    dragNodeConnLine(node, line, transPt) {
        var lineGraph = line.getRefGraph();
        if (!lineGraph) {
            return;
        }
        var nodePt = node.getPos();
        var position = lineGraph.getPos();
        var lenth = position.posList.length;
        var pt1 = position.posList[0];
        var dis1 = funcs.distancePoint(pt1, nodePt, 1);

        var pt2 = position.posList[lenth - 1];
        var dis2 = funcs.distancePoint(pt2, nodePt, 1);
        var destPt = pt1;
        if (dis1 > dis2) {
            destPt = pt2;
        }
        destPt.x += transPt.x;
        destPt.y += transPt.y;
        lineGraph.calScope(1);
    }

    judgeInRect(rect) {
        var nInRegion = false;
        var graphZoone = this._zone;
        if (graphZoone.left > rect.right
            || graphZoone.right < rect.left
            || graphZoone.top < rect.bottom
            || graphZoone.bottom > rect.top) {
            nInRegion = 0;
        }
        else {
            if (rect.posInRect(graphZoone.left, graphZoone.top)
                && rect.posInRect(graphZoone.right, graphZoone.top)
                && rect.posInRect(graphZoone.right, graphZoone.bottom)
                && rect.posInRect(graphZoone.left, graphZoone.bottom)) {
                nInRegion = true;
            }
            else {
                console.log("------------------");
            }
        }
        return nInRegion;
    }

    translate(tOffset, mapscale, multiTransFlag, mulSelLineList) {
        let preCnt = this.getLocalOrigin();
        this.translateSubData(tOffset, mapscale, multiTransFlag);
        this._position.offset(tOffset.x, tOffset.y);
        this.calScope(mapscale);
        // this.translateGradientFill(tOffset);
        this.translateAttachInfo(preCnt, tOffset, mapscale, multiTransFlag, mulSelLineList);
        this.setModified(1);
        return 0;
    }


    translate2DstPt(dstPt, mapscale, multiTransFlag) {
        let preCnt = this._zone.getCnt();
        let x = dstPt.x - preCnt.x;
        let y = dstPt.y - preCnt.y;
        this.translate({ x, y }, mapscale, multiTransFlag);
    }

    displayDashLineRectScope(ptlst, map, mapInfo) {
        if (ptlst.length != 10 || mapInfo.editMode == "autocad") {
            return;
        }
        map.save();
        map.setLineDash([5, 5]);
        map.beginPath();
        map.lineWidth = 2;
        map.strokeStyle = mapInfo.backColor.invert().toHexString();
        var pt0 = ptlst[0];
        var p0 = CoordTRFUtil.world2Screen(pt0, mapInfo);
        map.moveTo(p0.x, p0.y);
        for (var i = 1; i < 4; i++) {
            var pt = ptlst[i];
            var p = CoordTRFUtil.world2Screen(pt, mapInfo);
            map.lineTo(p.x, p.y);
        }
        map.lineTo(p0.x, p0.y);
        map.closePath();
        map.stroke();
        for (var i = 0; i < 8; i++) {
            var pt = ptlst[i];
            var p = CoordTRFUtil.world2Screen(pt, mapInfo);
            this.drawFocusPoint(map, p.x, p.y, "#0000ff");
        }

        map.setLineDash([]);
        map.beginPath();
        var pt5 = ptlst[8];
        var p5 = CoordTRFUtil.world2Screen(pt5, mapInfo);
        map.moveTo(p5.x, p5.y);

        var pt6 = ptlst[9];
        var p6 = CoordTRFUtil.world2Screen(pt6, mapInfo);
        map.lineTo(p6.x, p6.y);
        map.closePath();
        map.stroke();

        map.beginPath();
        map.lineWidth = 2;
        const r = 6;
        let sAngle = 90 * Math.PI / 180;
        let eAngle = 360 * Math.PI / 180;

        let rotv = this.getRadAngle();
        map.save();
        map.translate(p6.x, p6.y);
        map.rotate(-rotv);
        map.arc(0, 0, r, sAngle, eAngle, false);
        map.restore();

        map.lineTo(p6.x, p6.y);
        map.closePath();
        map.stroke();

        map.restore();
    }


    modifyCommonAttribute(obj) {
        var position = this.getPos();
        position.clone(obj.pos);
        this.setAngle(obj.angle);
        this.setUseful(obj.m_nUseful);
        if (this.getNewAdd() == 0 && obj.m_nNewAdd != 0) {
            this.setNewAdd(obj.m_nNewAdd);
        }
        this.setLink(obj.xlink);
    }

    chkInTranslating() {
        let translateFlag = true;
        let kind = this.getSelKind();
        if (kind > LGXEnums.LGXModGraphKind.CommonStSelKind && kind != LGXEnums.LGXModGraphKind.Drag_center) {
            translateFlag = false;
        }
        return translateFlag;
    }

    getLocalZoneInWorld() {
        return this.getZone();
        /*
        let orgWorldPt = this._zone.getCnt();
        var symScope = this.getLocalZone();
        var rotv = this.getRadAngle();
        var rotcnt = { x: 0, y: 0 };
        let x = symScope.left;
        let y = symScope.top;
        var lefttopPt = { x, y };
        var p1 = funcs.rotate(lefttopPt, rotcnt, rotv);
        p1.x = orgWorldPt.x + p1.x;
        p1.y = orgWorldPt.y + p1.y;

        x = symScope.right;
        y = symScope.top;
        var righttopPt = { x, y };
        var p2 = funcs.rotate(righttopPt, rotcnt, rotv);
        p2.x = orgWorldPt.x + p2.x;
        p2.y = orgWorldPt.y + p2.y;

        x = symScope.right;
        y = symScope.bottom;
        var rightbotPt = { x, y };
        var p3 = funcs.rotate(rightbotPt, rotcnt, rotv);
        p3.x = orgWorldPt.x + p3.x;
        p3.y = orgWorldPt.y + p3.y;

        x = symScope.left;
        y = symScope.bottom;
        var leftbotPt = { x, y };
        var p4 = funcs.rotate(leftbotPt, rotcnt, rotv);
        p4.x = orgWorldPt.x + p4.x;
        p4.y = orgWorldPt.y + p4.y;

        let multipos = new Coord.MultiPos();
        multipos.addPoint(p1);
        multipos.addPoint(p2);
        multipos.addPoint(p3);
        multipos.addPoint(p4);
        return multipos.getZone();
        */
    }

    getInlayerIdx() {
        if (!this.m_layer) {
            return 0;
        }
        return this.m_layer.getInlayerIdx(this);
    }

    chkClose = function () {
        let closeFlag = false;
        let type = this.m_graphType;
        if (type == LGXEnums.LGXGraphType.PolygonGraph_type
            || type == LGXEnums.LGXGraphType.RectGraph_type
            || type == LGXEnums.LGXGraphType.CircleGraph_type
            || type == LGXEnums.LGXGraphType.RegularPolygon_type
            || type == LGXEnums.LGXGraphType.MultiStar_type) {
            closeFlag = true;
        }
        else if (type == LGXEnums.LGXGraphType.LineGraph_type) {
            closeFlag = this.getClose();
        }
        return closeFlag;

    }

    getPath() { }

    setSymbol(s) {
        this._refSymbol = s;
        if (this.m_graphType == LGXEnums.LGXGraphType.LineGraph_type) {
            this.cloneSymbolInfo(s);
        }
        s.setBeenRefFlag(true);
    }
    getSymbol() { return this._refSymbol; }

    setPos(srcpos) {
        this.setPos_withoutNotify(srcpos);
        this.notifyToObserver();
    }
    getPos() { return this._position; }
    setPos_withoutNotify(srcpos) {
        if (this._position) {
            this._position.clone(srcpos);
            this.calControlPoint();
            this.calScope(1);
            this.resetLabelPos();
        }
        else {
            this._position = srcpos;
        }
    }

    getPosType() { return this._position.posType; }

    setStart(v) { this._startFlag = v; }
    getStart() { return this._startFlag; }

    setFinish(v) {
        let preFinsh = this._finishFlag;
        this._finishFlag = v;
        if (this._notifyFlag && this._newAddFlag && preFinsh == 0 && v == 1) {
            let count = this.dataChgObserverList.length;
            for (let i = 0; i < count; i++) {
                let observer = this.dataChgObserverList[i];
                observer.notifyNewGraphFinish(this);
            }
        }
    }
    getFinish() { return this._finishFlag; }

    getType() { return this._type; }
    getName() { return this._name; }

    setUseful(v) {
        let delflag = false;
        if (this._useful == 1 && v == 0) {
            delflag = true;
            if (this.m_topoRes) {
                this.m_topoRes.setUseful(0);
            }
            if (this.m_pLabelGraph) {
                this.m_pLabelGraph._useful = 0;
            }
        }
        this._useful = v;
        this.notifyToObserver(delflag);
    }
    getUseful() { return this._useful; }

    setActionSvc(v) { this._actionSvc = v; }

    //设置被选中，并且加入数据管理类选中图形队列中。单选时调用
    setSelect(v) {
        this._selected = v;
        this.notifySelectToObserver(v);
    }

    //多选时调用，把当前图形对象加入数据管理类选中图形队列中
    setToSelectList() {
        this.notifySelectToObserver(1);
    }
    forseSetSelect(v) { this._selected = v; }//强制设置选中标识，不通知图形管理类
    getSelect() { return this._selected; }

    setSelKind(v) { this._selKind = v; }
    getSelKind() { return this._selKind; }

    setModifing(v) { this._modifing = v; }
    getModifing() { return this._modifing; }
    setModified(v) { this._modified = v; }
    getModified() { return this._modified; }

    setHighLight(v) { this._highLight = v; }
    getHighLight() { return this._highLight; }

    setAngle(v) {
        this._angle = v;
        this.notifyToObserver();
    }
    getAngle() { return this._angle; }

    setTopoRes(v) { this.m_topoRes = v; }
    getTopoRes() { return this.m_topoRes; }

    getNewAdd() { return this._newAddFlag; }
    setNewAdd(newadd) { this._newAddFlag = newadd; }

    getLabel() { return this.m_pLabelGraph; }
    setLabel(v) {
        this.m_pLabelGraph = v;
        v.m_parentGraph = this;
    }
    setLock(v) { this._lockFlag = v; }
    getLock() { return this._lockFlag; }

    getZone() {
        var rect = new LXCOM.LGXRect(0, 0, 0, 0);
        rect.clone(this._zone);
        return rect;
    }

    getRotCnt() {
        let x = this._zone.getCnt().x;
        let y = this._zone.getCnt().y;
        return { x, y };
    }
    getRadAngle() {
        let rotv = this._angle * Math.PI / 180.0;
        return rotv;
    }

    getContainer() { return this.m_pContainer; }
    getChildList() { return this.m_tChildGraphLst; }
    addChild(p) {
        if (p == this) {
            return;
        }
        if (this.m_tChildGraphLst.indexOf(p) == -1) {
            this.m_tChildGraphLst.push(p);
            p.m_pContainer = this;
        }
    }

    insertChild(p, insertIndex) {
        if (p == this) {
            return;
        }
        if (this.m_tChildGraphLst.indexOf(p) == -1) {
            if (insertIndex == -1) {
                this.m_tChildGraphLst.push(p);
            }
            else {
                this.m_tChildGraphLst.splice(insertIndex, 0, p);
            }
            p.m_pContainer = this;
        }
    }

    removeChild(p) {
        let idx = this.m_tChildGraphLst.indexOf(p);
        if (idx >= 0) {
            this.m_tChildGraphLst.splice(idx, 1);
            p.m_pContainer = null;
        }
    }
    clearChilds() {
        this.m_tChildGraphLst.forEach(p => {
            p.m_pContainer = null;
        });
        this.m_tChildGraphLst.length = 0;
    }
    hasChild(p) {
        let flag = false;
        if (this.m_tChildGraphLst.indexOf(p) >= 0) {
            flag = true;
        }
        return flag;
    }
    getChildCount() {
        return this.m_tChildGraphLst.length;
    }
    getItemChildCount() {
        let itemCount = 0;
        let count = this.m_tChildGraphLst.length;
        for (let i = 0; i < count; i++) {
            let child = this.m_tChildGraphLst[i];
            if (child.chkIsContainerItem()) {
                itemCount++;
            }
        }
        return itemCount;
    }

    getItemChildList() {
        let list = [];
        let count = this.m_tChildGraphLst.length;
        for (let i = 0; i < count; i++) {
            let child = this.m_tChildGraphLst[i];
            if (child.chkIsContainerItem()) {
                list.push(child);
            }
        }
        return list;
    }

    translateChild(offsetPt, mapscale) {
        for (let i = 0; i < this.m_tChildGraphLst.length; i++) {
            let child = this.m_tChildGraphLst[i];
            child.translate(offsetPt, mapscale, false);
        }
        return;
    }

    chkIsContainerItem() {
        let flag = false;
        if (this._refSymbol) {
            let moldActionType = this._refSymbol.getMoldActionType();
            if (moldActionType == LGXEnums.moldActionType.item) {
                flag = true;
            }
        }
        return flag;
    }

    getChildIndex(p) {
        let idx = this.m_tChildGraphLst.indexOf(p);
        if (idx == -1) {
            idx = 0;
        }
        return idx;
    }



    modifyByCMD(isNew, cmd) {
        let rst = null;
        if (this._actionSvc) {
            rst = this._actionSvc.modifyByCMD(isNew, cmd);
        }
        this.notifyToObserver();
        return rst;
    }

    addObserver(observer) {
        if (this.dataChgObserverList.indexOf(observer) == -1) {
            this.dataChgObserverList.push(observer);
        }
    }

    notifyToObserver(delflag) {
        if (this._notifyFlag) {
            let count = this.dataChgObserverList.length;
            for (let i = 0; i < count; i++) {
                let observer = this.dataChgObserverList[i];
                observer.notifyGraphUpdate(this, delflag);
            }
        }
    }

    notifySelectToObserver(select) {
        let count = this.dataChgObserverList.length;
        for (let i = 0; i < count; i++) {
            let observer = this.dataChgObserverList[i];
            observer.notifySelect(this, select);
        }
    }

    scale(scalex, scaley, cntPt) {
        this.localScale.x = scalex;
        this.localScale.y = scaley;
    }
    setLink(v) { this.xlink = v; }
    getLink() { return this.xlink; }

    getExtDatas() {
        let dataInfo = {};
        dataInfo["xlink"] = this.xlink;
        return dataInfo;
    }

    resetLabelPos() {
        if (this.labelCtrlFlag == 0) {
            return;
        }
        let label = this.m_pLabelGraph;
        if (label) {
            label.resetLabelRect();
        }
    }
    translateSubData(tOffset, mapscale, multiTransFlag) {

    }

    translateAttachInfo(preCnt, tOffset, mapscale, multiTransFlag, mulSelLineList) {
        if (this.m_topoRes) {
            let curentCnt = this.getLocalOrigin();
            let inMulSelRegionLineLst = null;
            if (multiTransFlag && mulSelLineList && mulSelLineList.length > 0) {
                inMulSelRegionLineLst = mulSelLineList;
            }
            this.m_topoRes.notifyPosChang(preCnt, curentCnt, mapscale, inMulSelRegionLineLst);
        }
        if (!multiTransFlag) {
            let labelGraph = this.getLabel();
            if (labelGraph) {
                if (this.labelCtrlFlag == 0) {
                    labelGraph.setSelKind(1);
                    labelGraph.translate(tOffset, mapscale, false);
                    labelGraph.calScope(mapscale);
                    labelGraph.setModified(1);
                }
                else {
                    labelGraph.resetLabelRect();
                }
            }
            this.translateChild(tOffset, mapscale);
        }
        this.notifyToObserver();
        return 0;
    }

    chkExactIntersectRect(rect) { return false; }//精确判断图形与目标矩形相交

    chkIntersectRect(rect) {
        var graphZoone = this._zone;
        if (graphZoone.left > rect.right
            || graphZoone.right < rect.left
            || graphZoone.top < rect.bottom
            || graphZoone.bottom > rect.top) {
            return false;
        }
        else if (this.judgeInRect(rect)) {
            return true;
        }
        else {
            return this.chkExactIntersectRect(rect);
        }
    }

    setNotifyFlag(v) { this._notifyFlag = v; }

    chkSymUnitInViewPort(mapInfo, transformInfo) {
        let rect = CoordTRFUtil.transLocalRect2World(this._zone, 0, transformInfo);
        return funcs.chkRectInRect(rect, mapInfo.getViewPort());
    }

    convertPt2World(pt, transformInfo) {
        let featurePT = pt;
        if (transformInfo) {
            featurePT = CoordTRFUtil.transLocalPt2World(pt, this.getAngle(), transformInfo);
        }
        return featurePT;
    }

    rotateCoord(rotCnt, radAngle) {
        let srcPosCopy = this.getPosCopy();
        let angle = PositionUtil.rotatePos(srcPosCopy, rotCnt, radAngle);
        this.setPos(srcPosCopy);
        // this.rotateGradientFill(rotCnt, radAngle);

        this.rotateConnTopo(rotCnt, radAngle);
    }

    rotateConnTopo(rotCnt, radAngle) {
        let topoRes = this.getTopoRes();
        if (this.m_graphType != LGXEnums.LGXGraphType.LineGraph_type && topoRes) {
            let nodeList = topoRes.getConnNodeList();
            for (let i = 0; i < nodeList.length; i++) {
                let node = nodeList[i];
                let nodePt = node.getPos();
                var newPt = funcs.rotate(nodePt, rotCnt, radAngle);
                node.setPos(newPt.x, newPt.y);
            }
        }
    }

    rotateGradientFill(rotCnt, radAngle) { }
    chkValidFinish() {
        if (this.getStart() == 1
            && this.getUseful() == 1
            && this.getFinish() == 1) {
            return true;
        }
        else {
            return false;
        }
    }

    chkValidUnFinish() {
        if (this.getStart() == 1
            && this.getUseful() == 1
            && this.getFinish() == 0) {
            return true;
        }
        else {
            return false;
        }
    }

    getSizeDragInfo(kind) {
        let pt = { x: 0, y: 0 };
        let vector = new LXCOM.LGXVector();
        let ptlist = this.getScopeVertexPtLst(1);

        switch (kind) {
            case LGXEnums.LGXModGraphKind.Drag_leftTop:
                {
                    pt = ptlist[0];
                    let p1 = ptlist[0];
                    let p2 = ptlist[2];
                    vector.setBy2Pt(p1, p2);
                }
                break;

            case LGXEnums.LGXModGraphKind.Drag_rightTop:
                {
                    pt = ptlist[1];
                    let p1 = ptlist[1];
                    let p2 = ptlist[3];
                    vector.setBy2Pt(p1, p2);
                }
                break;
            case LGXEnums.LGXModGraphKind.Drag_RightBottom:
                {
                    pt = ptlist[2];
                    let p1 = ptlist[2];
                    let p2 = ptlist[0];
                    vector.setBy2Pt(p1, p2);
                }
                break;
            case LGXEnums.LGXModGraphKind.Drag_leftBottom:
                {
                    pt = ptlist[3];
                    let p1 = ptlist[3];
                    let p2 = ptlist[1];
                    vector.setBy2Pt(p1, p2);
                }
                break;

            case LGXEnums.LGXModGraphKind.Drag_TopMid:
                {
                    pt = ptlist[4];
                    let p1 = ptlist[0];
                    let p2 = ptlist[1];
                    vector.setBy2Pt(p1, p2);
                    vector.rotate(90);
                }
                break;
            case LGXEnums.LGXModGraphKind.Drag_RightMid:
                {
                    pt = ptlist[5];
                    let p1 = ptlist[1];
                    let p2 = ptlist[2];
                    vector.setBy2Pt(p1, p2);
                    vector.rotate(90);
                }
                break;
            case LGXEnums.LGXModGraphKind.Drag_BottomMid:
                {
                    pt = ptlist[6];
                    let p1 = ptlist[2];
                    let p2 = ptlist[3];
                    vector.setBy2Pt(p1, p2);
                    vector.rotate(90);
                }
                break;
            case LGXEnums.LGXModGraphKind.Drag_LeftMid:
                {
                    pt = ptlist[7];
                    let p1 = ptlist[3];
                    let p2 = ptlist[0];
                    vector.setBy2Pt(p1, p2);
                    vector.rotate(90);
                }
                break;
        }
        return { pt, vector };
    }

    getDirectConnOther() {
        if (this.m_graphType == LGXEnums.LGXGraphType.LineGraph_type) {
            return [];
        }

        let list = [];
        let label = this.getLabel();
        if (label) {
            list.push(label);
        }

        if (this.m_topoRes) {
            let connNodeList = this.m_topoRes.getConnNodeList();
            for (let i = 0; i < connNodeList.length; i++) {
                let node = connNodeList[i];
                let connLineList = node.getConnValidLineList();
                for (let n = 0; n < connLineList.length; n++) {
                    let connLine = connLineList[n];
                    let lineGraph = connLine.getRefGraph();
                    if (lineGraph) {
                        list.push(lineGraph);
                    }
                }
            }
        }
        return list;
    }

    drag2ModifyGradientInfo(newTransform) {
   
    }
}



export default { AbsGraph, LineUnitCounter, TransformInfo }
